﻿using System;
using System.Collections.Generic;
using System.Data.Entity.SqlServer;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Web.Http;
using Microsoft.Ajax.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WebServiceTMS.Helpers;

namespace WebServiceTMS.Controllers
{
    public class TaskController : ApiController
    {
        //POST api/Task/AddNewTask
        [HttpPost]
        [ActionName("AddNewTask")]
        public HttpResponseMessage AddNewTask(HttpRequestMessage request)
        {
            try
            {
                var content = request.Content;
                var jsonContent = content.ReadAsStringAsync().Result;
                var userObject = JObject.Parse(jsonContent);
                var tmp = new Dictionary<string, string>();
                foreach (KeyValuePair<String, JToken> resp in userObject)
                {
                    tmp.Add(resp.Key, resp.Value.ToString());
                }

                if (tmp.Count > 0)
                {
                    string goalId = null;
                    bool isSuccessGoalId = tmp.TryGetValue("GoalId", out goalId);
                    string userId = null;
                    bool isSuccessUserId = tmp.TryGetValue("UserId", out userId);
                    string taskName = null;
                    bool isSuccessTaskName = tmp.TryGetValue("Name", out taskName);
                    string taskDescription = null;
                    bool isSuccessTaskDescription = tmp.TryGetValue("Description", out taskDescription);
                    string assignedTo = null;
                    bool isSuccessAssignedTo = tmp.TryGetValue("AssignedTo", out assignedTo);
                    string priority = null;
                    bool isSuccessPriority = tmp.TryGetValue("Priority", out priority);
                    string startDate = null;
                    bool isSuccessStartDate = tmp.TryGetValue("StartDate", out startDate);
                    string finishDate = null;
                    bool isSuccessFinishDate = tmp.TryGetValue("FinishDate", out finishDate);
                    goalId = TMSCryptography.Decrypt(goalId);
                    userId = TMSCryptography.Decrypt(userId);
                    if (isSuccessGoalId && isSuccessUserId && isSuccessTaskName && isSuccessTaskDescription &&
                        isSuccessAssignedTo && isSuccessPriority && isSuccessStartDate && isSuccessFinishDate)
                    {
                        int goalIdNumeric;
                        bool isGoalIdANumber = int.TryParse(goalId, out goalIdNumeric);
                        int userIdNumeric;
                        bool isUserIdANumber = int.TryParse(userId, out userIdNumeric);
                        int assignedToNumeric;
                        bool isAssignedToNumberic = true;
                        if (assignedTo != "0")
                        {
                            assignedTo = TMSCryptography.Decrypt(assignedTo);
                            isAssignedToNumberic = int.TryParse(assignedTo, out assignedToNumeric);
                        }
                        else
                            assignedToNumeric = 0;
                        var startDateDf = Convert.ToDateTime(startDate);
                        var finishDateDf = Convert.ToDateTime(finishDate);
                        if (isUserIdANumber && isGoalIdANumber && isAssignedToNumberic)
                        {
                            return AddNewTaskHelper(userIdNumeric, goalIdNumeric, taskName, taskDescription, assignedToNumeric,
                                StringGenerator.GetPriorityValue(priority), startDateDf, finishDateDf);
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "Parameter error");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Some parameters have wrong format or empty!");
                }
                return HttpResponseHelper.CreateHttpResponse("error", "Parameters list is empty");
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        //POST api/Task/RemoveTask
        [HttpPost]
        [ActionName("RemoveTask")]
        public HttpResponseMessage RemoveTask(HttpRequestMessage request)
        {
            try
            {
                var content = request.Content;
                var jsonContent = content.ReadAsStringAsync().Result;
                var userObject = JObject.Parse(jsonContent);
                var tmp = new Dictionary<string, string>();
                foreach (KeyValuePair<String, JToken> resp in userObject)
                {
                    tmp.Add(resp.Key, resp.Value.ToString());
                }

                if (tmp.Count > 0)
                {
                    string userId = null;
                    bool isSuccessUserId = tmp.TryGetValue("UserId", out userId);
                    string taskId = null;
                    bool isSuccessTaskId = tmp.TryGetValue("TaskId", out taskId);
                    userId = TMSCryptography.Decrypt(userId);
                    taskId = TMSCryptography.Decrypt(taskId);
                    if (isSuccessUserId && isSuccessTaskId)
                    {
                        int userIdNumeric;
                        bool isUserIdANumber = int.TryParse(userId, out userIdNumeric);
                        int taskIdNumeric;
                        bool isTaskIdNumber = int.TryParse(taskId, out taskIdNumeric);
                        if (isUserIdANumber && isTaskIdNumber)
                        {
                            return RemoveTaskHelper(userIdNumeric, taskIdNumeric);
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "Parameter error");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Some parameters have wrong format or empty!");
                }
                return HttpResponseHelper.CreateHttpResponse("error", "Parameters list is empty");
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        //GET api/Task/GetAllTasksForUserBasedOnGoals
        [HttpGet]
        [ActionName("GetAllTasksForUserBasedOnGoals")]
        public HttpResponseMessage GetAllTasksForUserBasedOnGoals(HttpRequestMessage request)
        {
            try
            {
                var query = request.GetQueryNameValuePairs().ToDictionary(x => x.Key, x => x.Value);
                if (query.Count > 0)
                {
                    string userId = null;
                    bool isSuccessUserId = query.TryGetValue("UserId", out userId);
                    userId = TMSCryptography.Decrypt(userId);
                    if (isSuccessUserId)
                    {
                        int userIdNumeric;
                        bool isUserIdANumber = int.TryParse(userId, out userIdNumeric);
                        if (isUserIdANumber)
                        {
                            return GetAllTasksForUserBasedOnGoals(userIdNumeric);
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "Parameter error");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Some parameters have wrong format or empty!");
                }
                return HttpResponseHelper.CreateHttpResponse("error", "Parameters list is empty");
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        //GET api/Task/GetAllTasksInGoal
        [HttpGet]
        [ActionName("GetAllTasksInGoal")]
        public HttpResponseMessage GetAllTasksInGoal(HttpRequestMessage request)
        {
            try
            {
                var query = request.GetQueryNameValuePairs().ToDictionary(x => x.Key, x => x.Value);

                if (query.Count > 0)
                {
                    string goalId = null;
                    bool isSuccessGoalId = query.TryGetValue("GoalId", out goalId);
                    goalId = TMSCryptography.Decrypt(goalId);
                    if (isSuccessGoalId)
                    {
                        int goalIdNumeric;
                        bool isGoalIdANumber = int.TryParse(goalId, out goalIdNumeric);
                        if (isGoalIdANumber)
                        {
                            return GetAllTasksInGoalHelper(goalIdNumeric);
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "Parameter error");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Some parameters have wrong format or empty!");
                }
                return HttpResponseHelper.CreateHttpResponse("error", "Parameters list is empty");
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        //GET api/Task/GetAllUserTasks
        [HttpGet]
        [ActionName("GetAllUserTasks")]
        public HttpResponseMessage GetAllUserTasks(HttpRequestMessage request)
        {
            try
            {
                var query = request.GetQueryNameValuePairs().ToDictionary(x => x.Key, x => x.Value);

                if (query.Count > 0)
                {
                    string userId = null;
                    bool isSuccessUserId = query.TryGetValue("UserId", out userId);
                    userId = TMSCryptography.Decrypt(userId);
                    if (isSuccessUserId)
                    {
                        int userIdNumeric;
                        bool isUserIdANumber = int.TryParse(userId, out userIdNumeric);
                        if (isUserIdANumber)
                        {
                            return GetAllUserTasksHelper(userIdNumeric);
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "Parameter error");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Some parameters have wrong format or empty!");
                }
                return HttpResponseHelper.CreateHttpResponse("error", "Parameters list is empty");
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        //POST api/Task/EditTaskDescription
        [HttpPost]
        [ActionName("EditTaskDescription")]
        public HttpResponseMessage EditTaskDescription(HttpRequestMessage request)
        {
            try
            {
                var content = request.Content;
                var jsonContent = content.ReadAsStringAsync().Result;
                var userObject = JObject.Parse(jsonContent);
                var tmp = new Dictionary<string, string>();
                foreach (KeyValuePair<String, JToken> resp in userObject)
                {
                    tmp.Add(resp.Key, resp.Value.ToString());
                }

                if (tmp.Count > 0)
                {
                    string taskId = null;
                    bool isSuccessTaskId = tmp.TryGetValue("TaskId", out taskId);
                    string taskDescription = null;
                    bool isSuccessTaskDescription = tmp.TryGetValue("Description", out taskDescription);
                    taskId = TMSCryptography.Decrypt(taskId);
                    if (isSuccessTaskId && isSuccessTaskDescription)
                    {
                        int taskIdNumeric;
                        bool isTaskIdNumber = int.TryParse(taskId, out taskIdNumeric);
                        if (isTaskIdNumber)
                        {
                            return EditTaskDescriptionHelper(taskIdNumeric, taskDescription);
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "Parameter error");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Some parameters have wrong format or empty!");
                }
                return HttpResponseHelper.CreateHttpResponse("error", "Parameters list is empty");
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        //POST api/Task/ChangeTaskStatus
        [HttpPost]
        [ActionName("ChangeTaskStatus")]
        public HttpResponseMessage ChangeTaskStatus(HttpRequestMessage request)
        {
            try
            {
                var content = request.Content;
                var jsonContent = content.ReadAsStringAsync().Result;
                var userObject = JObject.Parse(jsonContent);
                var tmp = new Dictionary<string, string>();
                foreach (KeyValuePair<String, JToken> resp in userObject)
                {
                    tmp.Add(resp.Key, resp.Value.ToString());
                }

                if (tmp.Count > 0)
                {
                    string taskId = null;
                    bool isSuccessTaskId = tmp.TryGetValue("TaskId", out taskId);
                    string status = null;
                    bool isSuccessStatus = tmp.TryGetValue("Status", out status);
                    taskId = TMSCryptography.Decrypt(taskId);
                    if (isSuccessTaskId && isSuccessStatus)
                    {
                        int taskIdNumeric;
                        bool isTaskIdANumber = int.TryParse(taskId, out taskIdNumeric);
                        if (isTaskIdANumber)
                        {
                            return ChangeTaskStatusHelper(taskIdNumeric, status);
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "Parameter error");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Some parameters are empty!");
                }
                return HttpResponseHelper.CreateHttpResponse("error", "Parameters list is empty");
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        //POST api/Task/ChangeTaskPriority
        [HttpPost]
        [ActionName("ChangeTaskPriority")]
        public HttpResponseMessage ChangeTaskPriority(HttpRequestMessage request)
        {
            try
            {
                var content = request.Content;
                var jsonContent = content.ReadAsStringAsync().Result;
                var userObject = JObject.Parse(jsonContent);
                var tmp = new Dictionary<string, string>();
                foreach (KeyValuePair<String, JToken> resp in userObject)
                {
                    tmp.Add(resp.Key, resp.Value.ToString());
                }

                if (tmp.Count > 0)
                {
                    string taskId = null;
                    bool isSuccessTaskId = tmp.TryGetValue("TaskId", out taskId);
                    string priority = null;
                    bool isSuccessStatus = tmp.TryGetValue("Priority", out priority);
                    taskId = TMSCryptography.Decrypt(taskId);
                    if (isSuccessTaskId && isSuccessStatus)
                    {
                        int taskIdNumeric;
                        bool isTaskIdANumber = int.TryParse(taskId, out taskIdNumeric);
                        int priorityNumeric;
                        bool isPriorityANumber = int.TryParse(priority, out priorityNumeric);
                        if (isTaskIdANumber && isPriorityANumber)
                        {
                            return ChangeTaskPriorityHelper(taskIdNumeric, priorityNumeric);
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "Parameter error");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Some parameters are empty!");
                }
                return HttpResponseHelper.CreateHttpResponse("error", "Parameters list is empty");
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        //POST api/Task/ChangeTaskDates
        [HttpPost]
        [ActionName("ChangeTaskDates")]
        public HttpResponseMessage ChangeTaskDates(HttpRequestMessage request)
        {
            try
            {
                var content = request.Content;
                var jsonContent = content.ReadAsStringAsync().Result;
                var userObject = JObject.Parse(jsonContent);
                var tmp = new Dictionary<string, string>();
                foreach (KeyValuePair<String, JToken> resp in userObject)
                {
                    tmp.Add(resp.Key, resp.Value.ToString());
                }

                if (tmp.Count > 0)
                {
                    string taskId = null;
                    bool isSuccessTaskId = tmp.TryGetValue("TaskId", out taskId);
                    string startDate = null;
                    bool isSuccessStartDate = tmp.TryGetValue("StartDate", out startDate);
                    string finishDate = null;
                    bool isSuccessFinishDate = tmp.TryGetValue("FinishDate", out finishDate);
                    taskId = TMSCryptography.Decrypt(taskId);
                    if (isSuccessTaskId && isSuccessStartDate && isSuccessFinishDate)
                    {
                        int taskIdNumeric;
                        bool isTaskIdANumber = int.TryParse(taskId, out taskIdNumeric);
                        var startDateDf = Convert.ToDateTime(startDate);
                        var finishDateDf = Convert.ToDateTime(finishDate);
                        if (isTaskIdANumber)
                        {
                            return ChangeTaskDatesHelper(taskIdNumeric, startDateDf, finishDateDf);
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "Parameter error");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Some parameters are empty!");
                }
                return HttpResponseHelper.CreateHttpResponse("error", "Parameters list is empty");
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        //POST api/Task/AssignTaskToUser
        [HttpPost]
        [ActionName("AssignTaskToUser")]
        public HttpResponseMessage AssignTaskToUser(HttpRequestMessage request)
        {
            try
            {
                var content = request.Content;
                var jsonContent = content.ReadAsStringAsync().Result;
                var userObject = JObject.Parse(jsonContent);
                var tmp = new Dictionary<string, string>();
                foreach (KeyValuePair<String, JToken> resp in userObject)
                {
                    tmp.Add(resp.Key, resp.Value.ToString());
                }

                if (tmp.Count > 0)
                {
                    string taskId = null;
                    bool isSuccessTaskId = tmp.TryGetValue("TaskId", out taskId);
                    string assignedTo = null;
                    bool isSuccessAssignedTo = tmp.TryGetValue("AssignedTo", out assignedTo);
                    taskId = TMSCryptography.Decrypt(taskId);
                    assignedTo = TMSCryptography.Decrypt(assignedTo);
                    if (isSuccessTaskId && isSuccessAssignedTo)
                    {
                        int taskIdNumeric;
                        bool isTaskIdANumber = int.TryParse(taskId, out taskIdNumeric);
                        int assignedToNumeric;
                        bool isAssignedToANumber = int.TryParse(assignedTo, out assignedToNumeric);
                        if (isTaskIdANumber && isAssignedToANumber)
                        {
                            return AssignTaskToUserHelper(taskIdNumeric, assignedToNumeric);
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "Parameter error");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Some parameters are empty!");
                }
                return HttpResponseHelper.CreateHttpResponse("error", "Parameters list is empty");
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        //GET api/Task/GetTask
        [HttpGet]
        [ActionName("GetTask")]
        public HttpResponseMessage GetTask(HttpRequestMessage request)
        {
            try
            {
                var content = request.Content;
                var jsonContent = content.ReadAsStringAsync().Result;
                var userObject = JObject.Parse(jsonContent);
                var tmp = new Dictionary<string, string>();
                foreach (KeyValuePair<String, JToken> resp in userObject)
                {
                    tmp.Add(resp.Key, resp.Value.ToString());
                }

                if (tmp.Count > 0)
                {
                    string taskId = null;
                    bool isSuccessUserId = tmp.TryGetValue("TaskId", out taskId);
                    taskId = TMSCryptography.Decrypt(taskId);
                    if (isSuccessUserId)
                    {
                        int taskIdNumeric;
                        bool isTaskIdANumber = int.TryParse(taskId, out taskIdNumeric);
                        if (isTaskIdANumber)
                        {
                            return GetTaskHelper(taskIdNumeric);
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "Parameter error");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Some parameters have wrong format or empty!");
                }
                return HttpResponseHelper.CreateHttpResponse("error", "Parameters list is empty");
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        private HttpResponseMessage AddNewTaskHelper(int userId, int goalId, string name, string description,
            int assignedTo, int priority, DateTime startDate, DateTime finishDate)
        {
            try
            {
                using (var context=new TMSEntities())
                {
                    var newTask = new Tasks
                    {
                        Goal = goalId,
                        Name = name,
                        Description = description,
                        Priority = priority,
                        StartDate = startDate,
                        FinishDate = finishDate,
                        Status = "To Do"
                    };
                    var users = context.Users.ToList();
                    if (users.FirstOrDefault(u => u.Id == userId) != null)
                        newTask.CreatedBy = userId;
                    if (assignedTo != 0)
                        if (users.FirstOrDefault(u => u.Id == assignedTo) != null)
                            newTask.AssignedTo = assignedTo;
                    context.Tasks.Add(newTask);
                    context.SaveChanges();
                    return HttpResponseHelper.CreateHttpResponse("success", "");
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        private HttpResponseMessage RemoveTaskHelper(int userId, int taskId)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var user = context.Users.FirstOrDefault(u => u.Id == userId);
                    if (user != null)
                    {
                        var task = context.Tasks.FirstOrDefault(t => t.Id == taskId);
                        if (task != null)
                        {
                            if (user.Status == "Admin" || user.Status == "Manager" || task.CreatedBy == user.Id)
                            {
                                context.Tasks.Remove(task);
                                context.SaveChanges();
                                return HttpResponseHelper.CreateHttpResponse("success", "");
                            }
                            return HttpResponseHelper.CreateHttpResponse("error", "You have no permissions to remove this task");
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "There is no such task in the system");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Invalid user");
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        private HttpResponseMessage GetAllTasksInGoalHelper(int goalId)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var query = from t in context.Tasks
                        join g in context.Goals on t.Goal equals g.Id
                        join createdBy in context.Users on t.CreatedBy equals createdBy.Id
                        join assignedTo in context.Users on t.AssignedTo equals assignedTo.Id
                        where g.Id == goalId
                        select new TMSTask
                        {
                            Id = SqlFunctions.StringConvert((double) t.Id).Trim(),
                            Name = t.Name,
                            Description = t.Description,
                            GoalName = g.Name,
                            GoalId = SqlFunctions.StringConvert((double) g.Id).Trim(),
                            AssignedToName = assignedTo.Login,
                            AssignedToId = SqlFunctions.StringConvert((double) assignedTo.Id).Trim(),
                            Status = t.Status,
                            StartDate = t.StartDate.ToString(),
                            FinishDate = t.FinishDate.ToString(),
                            CreatedByName = createdBy.Login,
                            CreatedById = SqlFunctions.StringConvert((double) createdBy.Id).Trim(),
                            PriorityVal = t.Priority
                        };
                    return GetJsonTasks(query.ToArray());
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        private HttpResponseMessage GetAllUserTasksHelper(int userId)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var query = from t in context.Tasks
                        join g in context.Goals on t.Goal equals g.Id
                        join createdBy in context.Users on t.CreatedBy equals createdBy.Id
                        join assignedTo in context.Users on t.AssignedTo equals assignedTo.Id
                        where t.CreatedBy == userId ||
                              t.AssignedTo == userId
                        select new TMSTask
                        {
                            Id = SqlFunctions.StringConvert((double)t.Id).Trim(),
                            Name = t.Name,
                            Description = t.Description,
                            GoalName = g.Name,
                            GoalId = SqlFunctions.StringConvert((double)g.Id).Trim(),
                            AssignedToName = assignedTo.Login,
                            AssignedToId = SqlFunctions.StringConvert((double)assignedTo.Id).Trim(),
                            Status = t.Status,
                            StartDate = t.StartDate.ToString(),
                            FinishDate = t.FinishDate.ToString(),
                            CreatedByName = createdBy.Login,
                            CreatedById = SqlFunctions.StringConvert((double)createdBy.Id).Trim(),
                            PriorityVal = t.Priority
                        };
                    return GetJsonTasks(query.ToArray());
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        private HttpResponseMessage GetAllTasksForUserBasedOnGoals(int userId)
        {
            try
            {
                using (var context=new TMSEntities())
                {
                    var userGoals = (from g in context.Goals
                        join t in context.Teams on g.Id equals t.Goal
                        where t.TeamMember == userId
                        select g).ToArray();
                    var tasks = new List<TMSTask>();
                    for (var i = 0; i < userGoals.Count(); i++)
                    {
                        var userGoal = userGoals[i];
                        var goalTasks = from t in context.Tasks
                            join g in context.Goals on t.Goal equals g.Id
                            join createdBy in context.Users on t.CreatedBy equals createdBy.Id
                            join assignedTo in context.Users on t.AssignedTo equals assignedTo.Id
                            where g.Id == userGoal.Id
                            select new TMSTask
                            {
                                Id = SqlFunctions.StringConvert((double) t.Id).Trim(),
                                Name = t.Name,
                                Description = t.Description,
                                GoalName = g.Name,
                                GoalId = SqlFunctions.StringConvert((double) g.Id).Trim(),
                                AssignedToName = assignedTo.Login,
                                AssignedToId = SqlFunctions.StringConvert((double) assignedTo.Id).Trim(),
                                Status = t.Status,
                                StartDate = t.StartDate.ToString(),
                                FinishDate = t.FinishDate.ToString(),
                                CreatedByName = createdBy.Login,
                                CreatedById = SqlFunctions.StringConvert((double) createdBy.Id).Trim(),
                                PriorityVal = t.Priority
                            };
                        tasks.AddRange(goalTasks);
                    }
                    return GetJsonTasks(tasks.ToArray());
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        private HttpResponseMessage EditTaskDescriptionHelper(int taskId, string description)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var task = context.Tasks.FirstOrDefault(t => t.Id == taskId);
                    if (task != null)
                    {
                        task.Description = description;
                        context.SaveChanges();
                        return HttpResponseHelper.CreateHttpResponse("success", "");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "There is no such task in the system");
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        private HttpResponseMessage GetJsonTasks(TMSTask[] taskList)
        {
            if (taskList.Any())
            {
                for (var i = 0; i < taskList.Count(); i++)
                {
                    taskList[i].Id = TMSCryptography.Encrypt(taskList[i].Id);
                    taskList[i].AssignedToId = TMSCryptography.Encrypt(taskList[i].AssignedToId);
                    taskList[i].CreatedById = TMSCryptography.Encrypt(taskList[i].CreatedById);
                    taskList[i].PriorityStr = StringGenerator.GetPriorityString(taskList[i].PriorityVal);
                    taskList[i].StartDate = Convert.ToDateTime(taskList[i].StartDate).ToShortDateString();
                    taskList[i].FinishDate = Convert.ToDateTime(taskList[i].FinishDate).ToShortDateString();
                }
                var jsonResponse = JsonConvert.SerializeObject(taskList);
                return HttpResponseHelper.CreateHttpResponse("success", jsonResponse);
            }
            return HttpResponseHelper.CreateHttpResponse("success", "[]");
        }

        private HttpResponseMessage ChangeTaskStatusHelper(int taskId, string status)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var task = context.Tasks.FirstOrDefault(t => t.Id == taskId);
                    if (task != null)
                    {
                        task.Status = status;
                        context.SaveChanges();
                        return HttpResponseHelper.CreateHttpResponse("success", "");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "There is no such user!");
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        private HttpResponseMessage ChangeTaskPriorityHelper(int taskId, int priority)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var task = context.Tasks.FirstOrDefault(t => t.Id == taskId);
                    if (task != null)
                    {
                        task.Priority = priority;
                        context.SaveChanges();
                        return HttpResponseHelper.CreateHttpResponse("success", "");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "There is no such user!");
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        private HttpResponseMessage ChangeTaskDatesHelper(int taskId, DateTime startDateDf, DateTime finishDateDf)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var task = context.Tasks.FirstOrDefault(t => t.Id == taskId);
                    if (task != null)
                    {
                        task.StartDate = startDateDf;
                        task.FinishDate = finishDateDf;
                        context.SaveChanges();
                        return HttpResponseHelper.CreateHttpResponse("success", "");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "There is no such user!");
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        private HttpResponseMessage AssignTaskToUserHelper(int taskId, int assignedToId)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var task = context.Tasks.FirstOrDefault(t => t.Id == taskId);
                    var assignedTo = context.Tasks.FirstOrDefault(at => at.Id == assignedToId);
                    if (task != null)
                    {
                        if (assignedTo != null)
                        {
                            task.AssignedTo = assignedToId;
                            context.SaveChanges();
                            return HttpResponseHelper.CreateHttpResponse("success", "");
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "There is no such user you want to assign task!");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "There is no such user!");
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        private HttpResponseMessage GetTaskHelper(int taskId)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var users = context.Users.ToList();
                    var allGoals = context.Goals.ToList();
                    var task = from t in context.Tasks
                                where t.Id == taskId
                                select new TMSTask
                                {
                                    Id = SqlFunctions.StringConvert((double)t.Id).Trim(),
                                    Name = t.Name,
                                    Description = t.Description,
                                    GoalName = allGoals.First(g => g.Id == t.Goal).Name,
                                    GoalId = SqlFunctions.StringConvert((double)allGoals.First(g => g.Id == t.Goal).Id).Trim(),
                                    AssignedToName = users.FirstOrDefault(u => u.Id == t.AssignedTo).Login, //TODO exception when is null
                                    AssignedToId = SqlFunctions.StringConvert((double)t.AssignedTo).Trim(),
                                    Status = t.Status,
                                    StartDate = t.StartDate.ToShortDateString(),
                                    FinishDate = t.FinishDate.ToShortDateString(),
                                    CreatedByName = users.FirstOrDefault(u => u.Id == t.CreatedBy).Login, //TODO exception when is null
                                    CreatedById = SqlFunctions.StringConvert((double)t.CreatedBy).Trim(),
                                    PriorityStr = StringGenerator.GetPriorityString(t.Priority),
                                    PriorityVal = t.Priority
                                };
                    return HttpResponseHelper.CreateHttpResponse("success", "Task");
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }
    }
}
